package zmee.sso;

import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.dc.api.model.Account;
import kd.bos.dc.utils.AccountUtils;
import kd.bos.dc.utils.MCDBUtil;
import kd.bos.dc.utils.SQLUtils;
import kd.bos.exception.BosErrorCode;
import kd.bos.exception.ErrorCode;
import kd.bos.exception.KDBizException;
import kd.bos.exception.KDException;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.login.utils.ErrorCodeUtils;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
import kd.bos.workflow.engine.msg.ctx.MessageContext;
import net.sf.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

@SuppressWarnings("all")
/**
 * @program: CommonUtil
 * @description: 工具类
 * @author: nichengchi
 * @create: 2021-05-12 09:03
 **/

public class YSCommonUtil {

    private static Log logger = LogFactory.getLog(YSCommonUtil.class);
    private static ErrorCode ErrorCode=new ErrorCode("CommonUtil_ERROR","");
    /**
     * 获取accessToken
     * @param appId 第三方应用编码
     * @param appsecuret 第三方应用密码
     * @param user 登录账号
     * @param userType 登录类型
     * @return
     */
    public static String getaccessToken(String appId,String appsecuret,String user,String userType)  {
        //获取租户ID、数据中心ID、苍穹地址等公共参数
        Object accountIdObj= SystemParamServiceHelper.getPublicParameter("zjmi_accountid");
        Object tenantIdObj= SystemParamServiceHelper.getPublicParameter("zjmi_tenantid");
        Object addressObj= SystemParamServiceHelper.getPublicParameter("zjmi_address");
        if(accountIdObj==""||tenantIdObj==""||addressObj==""){
            throw new KDBizException("租户ID、数据中心ID、苍穹地址存在未填写的情况，请检查并填写！！");
        }
        //获取apptoken
        String accessToken = "";
        String appToken = "";
        String address=addressObj.toString();
        String tenantid=tenantIdObj.toString();
        String accountId=accountIdObj.toString();
        String getapptokenUrl="http://"+address+"/ierp/api/getAppToken.do";
        OutputStreamWriter out = null;
        BufferedReader in = null;
        JSONObject apptokenInfo = new JSONObject();
        apptokenInfo.put("appId",appId );
        apptokenInfo.put("appSecuret",appsecuret);
        apptokenInfo.put("tenantid",tenantid);
        apptokenInfo.put("accountId",accountId);
        apptokenInfo.put("language","zh_CN");
        try {
            URL restUrl = new URL(getapptokenUrl);
            HttpURLConnection conn = (HttpURLConnection) restUrl.openConnection();
            //请求方式
            conn.setRequestMethod("POST");
            //发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(),"UTF-8");
            //发送请求参数
            out.write(apptokenInfo.toString());
            //flush输出流的缓冲
            out.flush();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line="";
            String result = "";
            while ((line = in.readLine()) != null) {
                result +=  line;
            }
            JSONObject apptokenOjbect = JSONObject.fromObject(result);
            //获取app_token
            appToken=apptokenOjbect.getJSONObject("data").getString("app_token");
            if(StringUtils.isEmpty(appToken)){
                throw new KDBizException("未获取到apptoken！！");
            }
        }catch (MalformedURLException e) {
            e.printStackTrace();
            logger.error("获取apptoken失败，服务器异常："+e);
            throw new KDException(ErrorCode,"获取apptoken失败，服务器异常"+e.toString());
        } catch (ProtocolException e) {
            e.printStackTrace();
            throw new KDException(ErrorCode,"获取apptoken失败，服务器异常"+e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            throw new KDException(ErrorCode,"获取apptoken失败，服务器异常"+e.toString());
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        //获取accesstoken
        String getaccesstokenUrl="http://"+address+"/ierp/api/login.do";
        JSONObject accesstokenInfo = new JSONObject();
        accesstokenInfo.put("user",user);
        accesstokenInfo.put("apptoken",appToken);
        accesstokenInfo.put("tenantid",tenantid);
        accesstokenInfo.put("accountId",accountId);
        accesstokenInfo.put("usertype",userType);
        try {
            URL loginUrl = new URL(getaccesstokenUrl);
            HttpURLConnection conn = (HttpURLConnection) loginUrl.openConnection();
            //请求方式
            conn.setRequestMethod("POST");
            //发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            //获取URLConnection对象对应的输出流
            out = new OutputStreamWriter(conn.getOutputStream(),"UTF-8");
            //发送请求参数
            out.write(accesstokenInfo.toString());
            //flush输出流的缓冲
            out.flush();
            // 定义 BufferedReader输入流来读取URL的响应
            in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line="";
            String result = "";
            while ((line = in.readLine()) != null) {
                result +=  line;
            }
            JSONObject apptokenOjbect = JSONObject.fromObject(result);
            //获取access_token
            accessToken=apptokenOjbect.getJSONObject("data").getString("access_token");
            if(StringUtils.isEmpty(accessToken)){
                throw new KDBizException ("未获取到accessToken！！");
            }
        }catch (MalformedURLException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取accessToken失败，服务器异常"+e.toString());
        } catch (ProtocolException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取accessToken失败，服务器异常"+e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取accessToken失败，服务器异常"+e.toString());
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return accessToken;
    }

    /**
     * 获取EAS影像地址
     * @param bosType 单据bosType
     * @param billId 单据billId
     * @param appId  第三方应用编码
     * @param appSecuret  第三方应用密码
     * @param user 登录账号
     * @param userType 登录账号类型
     * @return
     */
    public static String geteasimageUrl(String bosType,String billId,String appId,String appSecuret,String user,String userType){
        String imageUrl = "";
        //获取公共参数-苍穹地址
        Object addressObj= SystemParamServiceHelper.getPublicParameter("zjmi_address");
        if(addressObj==""){
            throw new KDBizException("公共参数-苍穹地址未填写，请检查！！");
        }
        String address=addressObj.toString();
        String url="http://"+address+"/ierp/kapi/app/iscb/meta_1B6C7799_EXECUTE";
        JSONObject inFo = new JSONObject();
        inFo.put("bosType",bosType);
        inFo.put("billID",billId);
        String accessToken= YSCommonUtil.getaccessToken(appId,appSecuret,user,userType);
        try {
            URL restUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection) restUrl.openConnection();
            //请求方式
            conn.setRequestMethod("POST");
            //发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            conn.setRequestProperty("access_token", accessToken);
            //获取URLConnection对象对应的输出流
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(),"UTF-8");
            //发送请求参数
            out.write(inFo.toString());
            //flush输出流的缓冲
            out.flush();
            // 定义 BufferedReader输入流来读取URL的响应
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            String line="";
            String result = "";
            while ((line = in.readLine()) != null) {
                result +=  line;
            }
            JSONObject resultOjbect = JSONObject.fromObject(result);
            //获取app_token
            if(resultOjbect.getJSONObject("data").containsKey("message")){
                throw new KDBizException ("获取影像地址失败！！"+resultOjbect.getJSONObject("data").getString("message"));
            }
            imageUrl=resultOjbect.getJSONObject("data").getString("result");
        }catch (MalformedURLException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取影像地址失败，服务器异常"+e.toString());
        } catch (ProtocolException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取影像地址失败，服务器异常"+e.toString());
        } catch (IOException e) {
            e.printStackTrace();
            throw new KDException (ErrorCode,"获取影像地址失败，服务器异常"+e.toString());
        }
        return imageUrl;
    }
    /**
     * 根据ids获取某单据单个字段集合
     * @param ids 单据id集合
     * @param colum 单据字段标识
     * @return
     */
    public static List<String> getSelectColumByIds(String entryName,String colum,List<Long> ids){
        QFilter filter = new QFilter("id", QCP.in, ids);
        List<String> colList = new ArrayList<>();
        Map<Object, DynamicObject> objectMap = BusinessDataServiceHelper.loadFromCache(entryName, colum, new QFilter[]{filter});
        if(objectMap != null && objectMap.size() > 0){
            List<DynamicObject> collect = objectMap.values().stream().collect(Collectors.toList());
            for(DynamicObject object : collect){
                String col = object.getString(colum);
                if(!colList.contains(col)){
                    colList.add(col);
                }
            }
        }
        return colList;
    }

    public static List<String> getNodeColumnByBusinessKeys(String entryName,String colum,List<String> BusinessKeys){

        QFilter filter = new QFilter("businesskey", QCP.in, BusinessKeys);
        //QFilter filter = new QFilter("businesskey", QCP.equals, BusinessKeys.get(0).toString());

        List<String> colList = new ArrayList<>();
        //DynamicObject dynamicObject = BusinessDataServiceHelper.loadSingle(entryName, colum, new QFilter[]{filter});
        Map<Object, DynamicObject> objectMap = BusinessDataServiceHelper.loadFromCache(entryName, colum, new QFilter[]{filter});
        if(objectMap != null && objectMap.size() > 0){
            List<DynamicObject> collect = objectMap.values().stream().collect(Collectors.toList());
            for(DynamicObject object : collect){
                String col = object.getString(colum);
                if(!colList.contains(col)){
                    colList.add(col);
                }
            }
        }
        logger.info("测试");
        return colList;
    }

    /**
     * 根据业务单据id获取节点名称
     * @param accountId 数据中心ID
     * @param tenantId
     * @param messageContext
     * @return
     */
    public static String getNodeName(String accountId, String tenantId, MessageContext messageContext){
        String nodeName = "";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = getConnect(accountId, tenantId);
            String sql = "select fname from t_wf_task where fbusinesskey = ?";
            pstmt = getPreparedStatement(conn,sql,new String[]{messageContext.getBusinessKey()});
            rs = pstmt.executeQuery();
            if (rs.next()) {
                nodeName = rs.getString("fname");
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("zjmi.cloud.util.CommonUtil.getNodeName："+e);
        } finally {
            SQLUtils.cleanup(rs, pstmt, conn);
        }
        return nodeName;
    }

    /**
     * DBUtils
     * @param accountId
     * @param tenantId
     * @return
     */
    public static Connection getConnect(String accountId, String tenantId){
        Connection conn = null;
        try {
            Account currentCenter = AccountUtils.getCorrectAccount(accountId, tenantId);
            Properties dataBaseProperties = AccountUtils.getTenantDBInfo(currentCenter);
            if (dataBaseProperties == null) {
                logger.error(ErrorCodeUtils.getDBIntralError());
                throw new KDException(BosErrorCode.configNotFound, new Object[]{ErrorCodeUtils.getDBIntralError()});
            }else{
                conn = MCDBUtil.getConnection(dataBaseProperties);
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("zjmi.cloud.util.CommonUtil.getConnect:"+e);
        }
        return conn;
    }

    /**
     * DBUtils
     * @param conn
     * @param sql
     * @param vals
     * @return
     */
    public static PreparedStatement getPreparedStatement(Connection conn, String sql, String[] vals){
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            for(int i=1;i<= vals.length; i++){
                pstmt.setString(i, vals[i-1]);
            }
        } catch (SQLException e) {
            e.printStackTrace();
            logger.info("zjmi.cloud.util.CommonUtil.getPreparedStatement:"+e);
        }
        return pstmt;
    }
}
